package com.ayq.activiti.manager.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class ActivitiRabbitMqConfig{

  @Autowired
  private CachingConnectionFactory connectionFactory;

  @Autowired
  private SimpleRabbitListenerContainerFactoryConfigurer factoryConfigurer;

  /**
   * 单一消费者
   *
   * @return SimpleRabbitListenerContainerFactory
   */
  @Bean(name = ActivitiRabbitMqConfig.LISTENER_CONTAINER_SINGLE)
  public SimpleRabbitListenerContainerFactory listenerContainer() {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setMessageConverter(new Jackson2JsonMessageConverter());
    factory.setConcurrentConsumers(1);
    factory.setMaxConcurrentConsumers(1);
    factory.setPrefetchCount(1);
    factory.setTxSize(1);
    factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
    factory.setReceiveTimeout(3000L);
    return factory;
  }

  /**
   * 多个消费者
   *
   * @return SimpleRabbitListenerContainerFactory
   */
  @Bean(name = ActivitiRabbitMqConfig.LISTENER_CONTAINER_MULTI)
  public SimpleRabbitListenerContainerFactory multiListenerContainer() {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factoryConfigurer.configure(factory, connectionFactory);
    factory.setMessageConverter(new Jackson2JsonMessageConverter());
    factory.setAcknowledgeMode(AcknowledgeMode.NONE);
    factory.setConcurrentConsumers(100);
    factory.setMaxConcurrentConsumers(100);
    factory.setPrefetchCount(5);
    return factory;
  }

  @Bean
  public RabbitTemplate rabbitTemplate() {
    connectionFactory.setPublisherConfirms(true);
    connectionFactory.setPublisherReturns(true);
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
    rabbitTemplate.setMandatory(true);
    rabbitTemplate.setConfirmCallback(
        (correlationData, ack, cause) -> {
//          log.info("确认信息:数据({}),应答({}),失败原因({})", correlationData, ack, cause)
          if(!ack){
            log.info("处理事件失败！失败信息：eventLogStr");
          }
        });
    rabbitTemplate.setReturnCallback(
        (message, replyCode, replyText, exchange, routingKey) ->
            log.info(
//                "反馈信息:交换机({}),路由({}),回应编码({}),回应文字({}),消息:{}",
                exchange,
                routingKey,
                replyCode,
                replyText,
                message));
    return rabbitTemplate;
  }

  /**
   * 单一侦听
   */
  public static final String LISTENER_CONTAINER_SINGLE = "LISTENER_CONTAINER_SINGLE";
  /**
   * 多侦听
   */
  public static final String LISTENER_CONTAINER_MULTI = "LISTENER_CONTAINER_MULTI";

  /**
   *
   * <p>节点信息更新队列</p>
   * @Author ayq
   * @Date 2021/4/22 14:56
   */
  final public static String ACTIVITI_NODE_INFO_UPDATE_QUEUE = "ACTIVITI_NODE_INFO_UPDATE_QUEUE";

  /**
   *
   * <p>节点信息更新交换机</p>
   * @Author ayq
   * @Date 2021/4/22 14:56
   */
  final public static String ACTIVITI_NODE_INFO_UPDATE_EXCHANGE = "ACTIVITI_NODE_INFO_UPDATE_EXCHANGE";

  /**
   *
   * <p>业务历史审核意见队列</p>
   * @Author ayq
   * @Date 2021/4/22 14:56
   */
  final public static String ACTIVITI_TASK_OPINION_LIST_QUEUE = "ACTIVITI_TASK_OPINION_LIST_QUEUE";

  /**
   *
   * <p>业务历史审核意见交换机</p>
   * @Author ayq
   * @Date 2021/4/22 14:56
   */
  final public static String ACTIVITI_TASK_OPINION_LIST_EXCHANGE = "ACTIVITI_TASK_OPINION_LIST_EXCHANGE";

  /**
   *
   * <p>节点信息更新路由key</p>
   * @Author ayq
   * @Date 2021/4/22 14:56
   */
  final public static String ACTIVITI_NODE_INFO_UPDATE = "activiti.node.info.update";

  /**
   *
   * <p>业务历史审核意见路由key</p>
   * @Author ayq
   * @Date 2021/4/22 14:56
   */
  final public static String ACTIVITI_TASK_OPINION_LIST = "activiti.task.opinion.list";

  @Bean(ACTIVITI_NODE_INFO_UPDATE_QUEUE)
  public Queue activitiNodeInfoUpdateQueue() {
    return new Queue(ACTIVITI_NODE_INFO_UPDATE_QUEUE, true);
  }

  @Bean(ACTIVITI_TASK_OPINION_LIST_QUEUE)
  public Queue activitiTaskOpinionListQueue() {
    return new Queue(ACTIVITI_TASK_OPINION_LIST_QUEUE, true);
  }

  @Bean( ACTIVITI_TASK_OPINION_LIST_EXCHANGE)
  public DirectExchange activitiTaskOpinionListExchange() {
    return new DirectExchange( ACTIVITI_TASK_OPINION_LIST_EXCHANGE,true,false);
  }

  @Bean(ACTIVITI_NODE_INFO_UPDATE_EXCHANGE)
  public DirectExchange activitiNodeInfoUpdateExchange() {
    return new DirectExchange(ACTIVITI_NODE_INFO_UPDATE_EXCHANGE,true,false);
  }

  @Bean
  public Binding bindingExchangeOne(@Qualifier(ACTIVITI_NODE_INFO_UPDATE_QUEUE) Queue queuea, @Qualifier(ACTIVITI_NODE_INFO_UPDATE_EXCHANGE) DirectExchange exchange) {
    return BindingBuilder.bind(queuea).to(exchange).with(ACTIVITI_NODE_INFO_UPDATE);
  }

  @Bean
  public Binding bindingExchangeTwo(@Qualifier(ACTIVITI_TASK_OPINION_LIST_QUEUE) Queue queuea, @Qualifier(ACTIVITI_TASK_OPINION_LIST_EXCHANGE) DirectExchange exchange) {
    return BindingBuilder.bind(queuea).to(exchange).with(ACTIVITI_TASK_OPINION_LIST);
  }
}
